<?php
namespace app\common\process;

use think\Log;

class UserWallet extends Base {


    public function index() {
        $post = loader()->loadAny('request', 'tyyh\\UserWallet')->index();
        $wallet = loader()->loadModel('tyyh\\UserWallet')->getWallet($post['uid']);
        $this->assign('wallet', $wallet);
        return $this->fetch();
    }

    //余额充值订单列表
    public function balance_order_private_list($fun = null) {
        $post = loader()->loadAny('request', 'tyyh\\UserWallet')->balance_order_private_list();
        $model = loader()->loadModel('tyyh\\UserWalletBalanceOrder');

        loader()->loadAny('search', 'tyyh\\UserWallet')->balance_order_private_list($model, $post);

        if(is_callable($fun)) {
            $fun($model);
        }
        if($post['limit']) {
            $list = $model->paginate($post['limit']);
        } else {
            $list = $model->select();
        }
        $this->assign('list', $list);
        return $this->fetch();
    }

    //余额变动列表
    public function user_wallet_balance_log($fun = null) {
        $post = loader()->loadAny('request', 'tyyh\\UserWallet')->user_wallet_balance_log();
        $model = loader()->loadModel('tyyh\\UserWalletBalanceLog');

        loader()->loadAny('search', 'tyyh\\UserWallet')->user_wallet_balance_log($model, $post);

        if(is_callable($fun)) {
            $fun($model);
        }
        if($post['limit']) {
            $list = $model->paginate($post['limit']);
        } else {
            $list = $model->select();
        }
        $this->assign('list', $list);
        return $this->fetch();
    }

    public function balance_order() {
        $post = loader()->loadAny('request', 'tyyh\\UserWallet')->balance_order();
        $validate = loader()->loadValidate('tyyh\\UserWallet');
        if(!$validate->scene('balance_order')->check($post)) {
            $this->error($validate->getError());
        }

        $balance = loader()->loadAny('activity')->index('Balance', $post['money']);

        $model = loader()->loadModel('tyyh\\UserWalletBalanceOrder');
        $model->save([
            'uid'          => $post['uid'],
            'money'        => $post['money'],
            'balance'      => $balance,
            'aid'          => $post['aid'],
            'out_trade_no' => loader()->loadTool('Number')->balance_order_out_trade_no(),
            'sub_mch_id'   => $post['sub_mch_id']
        ]);
        $this->assign('id', $model->id);
        return $this->success('保存成功');
    }

    public function balance_order_pay() {
        $app = loadTool('Wechat')->payment();
        $options = loadStorage('Login')->token2options();
        $redis = loader()->loadAny('redis', 'redis');
        $post = loader()->loadAny('request', 'tyyh\\UserWallet')->balance_order_pay();
        $cache = $redis->getArray($post['route'] . '_balance_order_pay_' . $post['id']);

        $validate = loader()->loadValidate('tyyh\\UserWalletBalanceOrderPay');
        //暂未写表单验证
        if(!$validate->scene('balance_order_pay')->check($post)) {
            $this->error($validate->getError());
        }
        
        if($cache) {
            //return $cache;
        }

        $order = loadOnly('Model')->find('tyyh\\UserWalletBalanceOrder', $post['id']);

        $attach = [
            'route' => $post['route']
        ];

        $result = $app->order->unify([
            'body' => '商品描述',
            'out_trade_no' => $order['out_trade_no'],
            'total_fee' => $order['money'] * 100,
            'notify_url' => 'https://' . $_SERVER['HTTP_HOST'] . '/miniprogram/user_wallet/balance_order_notify',
            'spbill_create_ip' => $post['ip'],
            'trade_type' => 'JSAPI',
            'openid' => $options['openid'],
            'profit_sharing' => '',
            'attach' => json_encode($attach)
        ]);

        //$statusEnum = loadEnum('OrderStatus');
        //$order->save(['status' => $statusEnum->code2key('guanbidingdan')]);

        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
            $prepayId = $result['prepay_id'];
            // 生成 JSAPI 支付参数
            $jssdk = $app->jssdk;
            $parameters = $jssdk->bridgeConfig($prepayId, false);
            $redis->setArray($post['route'] . '_balance_order_pay_' . $post['id'], $parameters, 7200);
            return $parameters;
        } else {
            $msg = $result['return_msg'] == 'OK' ? $result['err_code_des'] : $result['return_msg'];
            
            $errorMessage = "支付失败，订单号：{$order['out_trade_no']}，错误信息：{$msg}";
            Log::error($errorMessage);
            $this->error($msg);
        }
    }

    //支付充值回调
    public function balance_order_notify($app) {
        Log::info('notify--1');
        $response = $app->handlePaidNotify(function ($message, $fail) {
            Log::info('notify--message');
            Log::info('notify--json_encode($message)');
            if ($message['return_code'] === 'SUCCESS') {
                Log::info('notify--2');
                if ($message['result_code'] === 'SUCCESS') {
                    $orderModel = loadOnly('Model')->getModel('tyyh\\UserWalletBalanceOrder');
                    Log::info('notify--3');
                    $row = $orderModel->where(['out_trade_no' => $message['out_trade_no']])->find();
                    if($row['paytime'] > 0) {
                        return '';
                    }
                    try {
                        $orderModel->startTrans();
                        Log::info('notify--4');
                        if(empty($row)) {
                            Log::error($message['out_trade_no'] . '订单不存在');
                            throw new \Exception($message['out_trade_no'] . '订单不存在');
                        }
                        Log::info('notify--5');
                        $statusEnum = loadEnum('UserWalletBalanceOrderStatus');

                        $attach = $message['attach'];
                        $attach = json_decode($attach, true);

                        $row->save(['status' => $statusEnum->code2key('yiwancheng'), 'transaction_id' => $message['transaction_id'], 'paytime' => time(), 'route' => $attach['route']]);
                        $this->set_balance_ipl($row->uid, $row->balance);

                        Log::info('支付成功，订单号：' . $message['out_trade_no'] . ',支付前状态为' . $row['status']);
                        Log::info('notify--20');
                        $orderModel->commit();
                        Log::info('notify--21');
                    } catch(\Exception $e) {
                        $orderModel->rollback();
                        Log::error($e->getMessage());
                    }
                    Log::info('notify--22');
                    return true;
                } else {
                    $errorMessage = "支付失败，订单号：{$message['out_trade_no']}，错误信息：{$message['err_code_des']}";
                    Log::error($errorMessage);
                    return $fail('支付失败');
                }
            } else {
                $errorMessage = "支付通知通信失败，订单号：{$message['out_trade_no']}，错误信息：{$message['return_msg']}";
                Log::error($errorMessage);
                return $fail('通信失败');
            }
        });
        return $response;
    }


    //修改钱包余额，实际执行
    public function set_balance_ipl($uid, $num) {
        $walletModel = loadOnly('Model')->getModel('tyyh\\UserWallet');
        $wallet = $walletModel->getWallet($uid);
        $before = $wallet->balance;
        $after = $before + $num;
        $logModel = loadOnly('Model')->getModel('tyyh\\UserWalletBalanceLog');
        $logModel->id = null;
        $logModel->isUpdate(false)->save([
            'uid'    => $uid,
            'num'    => $num,
            'before' => $before,
            'after'  => $after
        ]);
        $wallet->balance = $after;
        $wallet->save();
    }

    //用户余额退款
    public function user_wallet_balance_refund () {
        $post = loader()->loadAny('request', 'tyyh\\UserWallet')->user_wallet_balance_refund();
        $validate = loadValidate('tyyh\\UserWallet');
        if(!$validate->scene('user_wallet_balance_refund')->check($post)) {
            $this->error($validate->getError());
        }
        $model = loadModel('tyyh\\UserWalletBalanceRefund');
        $model->save([
            'uid'                 => $post['uid'],
            'oid'                 => $post['oid'],
            'refund_out_trade_no' => loader()->loadTool('Number')->balance_refund_out_trade_no()
        ]);
        $this->assign('id', $model->id);
        return $this->success('保存成功');
    }

    //用户取消余额退款
    public function cancel_balance_refund () {
        $post = loader()->loadAny('request', 'tyyh\\UserWallet')->cancel_balance_refund();
        $validate = loadValidate('tyyh\\UserWallet');
        if(!$validate->scene('cancel_balance_refund')->check($post)) {
            $this->error($validate->getError());
        }
        $row = loader()->loadAny('only', 'tyyh\\UserWalletBalanceRefund')->get_row($post['id']);
        $row->status = loadEnum('UserWalletBalanceRefundStatus')->code2key('yiquxiao');
        $row->save();
        return $this->success('保存成功');
    }

    //退款单退款
    public function refund_ipl($id) {
        $only = loader()->loadAny('only', 'tyyh\\UserWalletBalanceRefund');
        $row = $only->get_row($id);
        $order = loader()->loadModel('tyyh\\UserWalletBalanceOrder')->where('id', $row['oid'])->find();
        $wallet = loader()->loadModel('tyyh\\UserWallet')->getWallet($order['uid']);
        $app = loadTool('Wechat')->payment($order['route']);
        if($wallet->balance >= $order['balance']) {
            $result = $app->refund->byTransactionId($order['transaction_id'], $row['refund_out_trade_no'], $order['money'] * 100, $order['money'] * 100);
            $this->set_balance_ipl($order['uid'], $order['balance'] * -1);
        } else {
            $c = $order['balance'] - $wallet->balance;
            $money = $order['money'] - $c;
            if($money > 0) {
                $this->set_balance_ipl($order['uid'], $wallet->balance * -1);
                $result = $app->refund->byTransactionId($order['transaction_id'], $refund['refund_out_trade_no'], $order['money'] * 100, $money * 100);
            } else {
                throw new \Exception('余额不足');
            }
        }
        return true;
    }
}
